#!../ext/bin/ruby
#
# Copyright Bjorn De Meyer 2007. Can be used freely under the zlib license.
#
#

BEGIN { $:.unshift(File.dirname(__FILE__)); }
# Include this script's directory in Ruby's search path.

require 'rogaru'
include Rogaru

Rubygame.init()
END { Rubygame.quit() }

def screen_make(wide, high, fullscreen, doublebuf = true) 
	flags  = Rubygame::HWSURFACE | Rubygame::ANYFORMAT
	flags |= Rubygame::FULLSCREEN if fullscreen
	flags |= Rubygame::DOUBLEBUF  if doublebuf
	begin
		screen = Rubygame::Screen.new( [640, 480], 16, flags )
	rescue Rubygame::SDLError
		return nil
	end
	screen.title = 'Eruta'
	return screen
end 

def surface_load_solid(filename)
    # file = os.path.join('share', 'image', filename)
    begin
        surface = Rubygame::Surface.load_image(filename)
    rescue Rubygame::SDLError
        raise "Could not load image #{filename}"
		return nil
	end	
	return surface.to_display().set_alpha(255,0)
end	

def surface_load_colorkey(filename, colorkey = [255,0,255])
    # file = os.path.join('share', 'image', filename)
    begin
        surface = Rubygame::Surface.load_image(filename)
    rescue Rubygame::SDLError
        raise "Could not load image #{filename}"
		return nil
	end	
	surface.set_colorkey(colorkey)
	puts "Load #{filename} with color key"
	return surface.to_display_alpha()
end	

# Loads an image, prepares it for play.
def surface_load_alpha(filename)
    # file = os.path.join('share', 'image', filename)
    begin
        surface = Rubygame::Surface.load_image(filename)
    rescue Rubygame::SDLError
        raise "Could not load image #{filename}"
		return nil
	end	
	puts "Load #{filename} with alpha"
	return surface.to_display_alpha()
end	

def joystick_setup()
	joysticks = []
	stop = Rubygame::Joystick.num_joysticks - 1
	for joynum in 0..stop do
		puts "Setting up joystick: " + Rubygame::Joystick.get_name( joynum )
  		joysticks[joynum] = Rubygame::Joystick.new(joynum)
	end
	return joysticks
end

def event_setup(nomouse = true)
	queue   = Rubygame::EventQueue.new() { @autofetch = true }
	queue.ignore = [ Rubygame::MouseMotionEvent ] if nomouse
	return queue
end

def event_handle(event) 
	puts event.to_s
	return true if event.is_a?(Rubygame::QuitEvent) 
	return false
end

def main(fullscreen = false)
	queue 		= Utility.event_setup(true)
	screen  	= Utility.screen_make(640, 480, fullscreen)
	joysticks 	= Utility.joystick_setup()
	Tilemap::Tile.set_tile_directory( File.join("..", "share", "image", "tile")); 
	map = Tilemap::Map.load_from('test6_map.xml')

	clock       = Rubygame::Clock.new()
	ttf 		= Rubygame::TTF
	ttf.setup()
	font 		= ttf.new( File.join("..", "share", "font", "crystal.ttf"), 16)
	 
	screen.fill [ 0xff, 00, 00] ;
	start = Time.now()
	times = 1000
	i     = 0
	done = false
	speed = 1	
	mem_count, mem_size = *Utility.used_memory
	entname  = File.join("..", "share", "image", "sprite_test_1.png")
	entimage = Image.load_alpha(entname)
	player   = Tilemap::Entity.new(100, 200, entimage)
	map.entities.push player
	puts "Starting render."
	until done do
		i += 1
		if (i % 500) == 0 then
			mem_count, mem_size = *Utility.used_memory
		end
		#screen.fill([0,191,0])	
        map.draw_auto(screen)
		status = "#{speed} #{map.x} #{map.y} #{(clock.framerate).round} #{mem_count}"
		UI::Text.prepare_and_draw_text(screen, [10, 10], status, 100, font, [255,255,255])
		
		screen.flip()
		queue.each do 	
			| event | done = event_handle(event) 
			case event
			when Rubygame::KeyDownEvent  
				puts "#{event.key} #{Rubygame::K_F10}"
				done = true if event.key == Rubygame::K_F10
				map.vx = -speed if event.key == Rubygame::K_LEFT
				map.vy = -speed if event.key == Rubygame::K_UP
				map.vx =  speed if event.key == Rubygame::K_RIGHT
				map.vy =  speed if event.key == Rubygame::K_DOWN
				speed += 1 if event.key == Rubygame::K_KP_PLUS
				speed -= 1 if event.key == Rubygame::K_KP_MINUS
			when Rubygame::KeyUpEvent
				puts "#{event.key} #{Rubygame::K_F10}"
				done = true if event.key == Rubygame::K_F10
				map.vx = 0 if event.key == Rubygame::K_LEFT
				map.vy = 0 if event.key == Rubygame::K_UP
				map.vx = 0 if event.key == Rubygame::K_RIGHT
				map.vy = 0 if event.key == Rubygame::K_DOWN
			when Rubygame::JoyAxisEvent
				if event.axis == 1  then
						if event.value > 1000 then
							player.vy = 1 
						elsif event.value < -1000 then
							player.vy = -1 
						else 
							player.vy = 0
						end
				end
				if event.axis == 0  then
						if event.value > 1000 then
							player.vx = 1 
						elsif event.value < -1000 then
							player.vx = -1 
						else 
							player.vx = 0
						end
				end
			end
		end
		player.update
		# Move player
		map.advance
		# Animate map tiles.
		map.update(screen.w, screen.h)
		# Move map to correct position, limited to these lower corners.
		clock.tick
		# GC.enable ; GC.start; GC.disable
	end
	stop 	= Time.now()
	fps    = clock.framerate
	puts "Average FPS: #{fps}\n"
	return 0
end

def test_music() 
	mix = Rubygame::Mixer
	# Use the lines below to get rid of artsd and contact ALSA directly on Linux.
	# ARTSD happens to be buggy on my old, old linux distro. 
	if RUBY_PLATFORM =~ /linux/
		`killall artsd`
		ENV['SDL_AUDIODRIVER'] = "alsa"
	end	
	mix.open_audio( mix::DEFAULT_FREQUENCY, mix::DEFAULT_FORMAT, 2, 1024)
	puts "Using audi driver:" + mix.driver_name
	music = mix::Music
	
	mus = music.load_audio("../test/music_test.wav");
	
	puts('Testing fade_in 3 times 2000 ms.')
	mus.fade_in(3, 2000);
	puts('ERROR: Music not fading in') unless mus.fading_in?
	
	puts('Waiting for fading_in? to end');
	while mus.fading_in? do Thread.pass end	

	puts('Testing volume')
	mus.volume = 60;
	puts('ERROR: Volume is not 60') if 60 != mus.volume
	
	puts('Testing pause')
	mus.pause
	puts('ERROR: Music not paused') unless mus.paused?

	puts('Sleeping 1 second');
    sleep 1

	puts('Testing resume')
	mus.resume
	puts('ERROR: Music not resumed') unless mus.playing?
	
	puts('Playing until end')
	helper = 0
	while mus.playing? do Thread.pass end
	# Test playing of music to the end
	puts('Played until end')
	puts('ERROR: Music not ended') if mus.playing?
	
	puts('Testing play 1 times')
	mus.play(1)
	puts('ERROR: Music not playing') unless mus.playing?
		
	puts('Testing fade_out')
	mus.fade_out(2000);
	puts('ERROR: Music not fading out ') unless mus.fading_out?
	
    puts('Fading until end')
    while mus.playing? or mus.fading_out? do Thread.pass end
	# Test playing of music to the end

	puts('ERROR: Music not ended') if mus.playing?
	mix.close_audio
end

def play_music() 
	mix = Rubygame::Mixer
	# Use the lines below to get rid of artsd and contact ALSA directly on Linux.
	# ARTSD happens to be buggy on my old, old linux distro. 
	if RUBY_PLATFORM =~ /linux/
		`killall artsd`
		ENV['SDL_AUDIODRIVER'] = "alsa"
	end	
	mix.open_audio( mix::DEFAULT_FREQUENCY, mix::DEFAULT_FORMAT, 2, 128 * 16 )
	puts "Using audio driver:" + mix.driver_name
	puts 'Warning: SET_SDL_AUDIODRIVER to alsa for better sound quality.' if (mix.driver_name!= 'alsa') 
	music = mix::Music
	mus = music.load_audio("../test/music_test.wav");
	mus.play(-1)
end

# play_music()
main ARGV[0]

# music_thread = Thread.new do test_music() end
# main_thread  = Thread.new do main() end
# main_thread.join
# music_thread.join


# require 'rubygame_collide'
# Boundbox = Rubygame::Collide::Boundbox
# class Boundbox
# 	def self.new (x,y,h,w) 
# 		return self.make(x,y,h,w)
# 	end
# 
# 	def to_s
# 		return "Boundbox: x:#{x}, y:#{y}, h:#{h}, w:#{w}"
# 	end
# end	
# 
# 
# b1 = Boundbox.new(10,20,30,40);
# b2 = Boundbox.new(10,20,30,40);
# puts b1.to_s + " collides with " + b2.to_s + " #{b1.collide? b2}"
# b3 = Boundbox.new(40,61,30,40);
# puts b1.to_s + " collides with " + b3.to_s + " #{b1.collide? b3}"
# 
# b4 = Boundbox.new(70,80,10,10);
# b5 = Boundbox.new(80,90,20,20);
# puts b4.to_s + " collides radially with " + b5.to_s + " #{b4.collide_radial? b5}"

Rubygame.quit()
